package com.autumn.platform.auth.web.access;

import java.util.List;

import org.springframework.web.method.HandlerMethod;

import com.autumn.platform.auth.core.access.AccessStrategy;
import com.autumn.platform.auth.core.access.IPermission;
import com.autumn.platform.web.WebHolder;
import com.autumn.platform.web.request.IWebRequest;
import com.autumn.platform.web.resulthandler.context.HandlerMethodContextHolder;

public class HandlerMethodPermissionMapping extends AbstractWebPermissionMapping {

    private List<IHandlerMethodPermissionMapping> mappings;

    public void setMappings(List<IHandlerMethodPermissionMapping> mappings) {
        this.mappings = mappings;
    }

    @Override
    protected IPermission lookup(IWebRequest request) {
        HandlerMethod handlerMethod = HandlerMethodContextHolder.getHandlerMethod();
        if (null != handlerMethod) {
            AccessStrategy strategy = getAccessStrategy(handlerMethod);
            if (null != strategy) {
                switch (strategy.value()) {
                    case ANY:
                        return IPermission.ANY;
                    case SESSION:
                        return null == WebHolder.getSessionUser() ? null : IPermission.ANY;
                    default:
                        return this.lookup(request, handlerMethod);
                }
            }
            return this.lookup(request, handlerMethod);
        }
        return null;
    }

    /**
     * 根据请求处理方法获取权限
     * 
     * @param request
     * @param handlerMethod
     * @return
     */
    private IPermission lookup(IWebRequest request, HandlerMethod handlerMethod) {
        if (null != this.mappings) {
            for (IHandlerMethodPermissionMapping m : mappings) {
                IPermission p = m.lookup(request, handlerMethod);
                if (null != p) {
                    return p;
                }
            }
        }
        return null;
    }

    private AccessStrategy getAccessStrategy(HandlerMethod handlerMethod) {
        AccessStrategy strategy = handlerMethod.getMethodAnnotation(AccessStrategy.class);
        if (null != strategy) {
            return strategy;
        } else {
            return handlerMethod.getBeanType().getAnnotation(AccessStrategy.class);
        }
    }
}
